<?php
/**
 * 数据驱动
 *
 */
$dsn = C('mongo_pool.mongo');
define("MONGO_CONNECTION", 'mongodb://'.$dsn['server'].'/'.$dsn['db']);
define("MONGO_DB", $dsn['db']);

// Set these values to your Mongo database
//define("MONGO_CONNECTION", "mongodb://192.168.8.8:30000/oauth2");
//define("MONGO_DB", "oauth2");

include dirname(dirname(dirname(__FILE__)))."/lib/OAuth2.inc";

/**
 * Sample OAuth2 Library Mongo DB Implementation.
 */
class MongoOAuth2 extends OAuth2 {

  private $db;

  /**
   * Overrides OAuth2::__construct().
   */
  public function __construct() {
	parent::__construct();

	$mongo = new Mongo(MONGO_CONNECTION);
	$this->db = $mongo->selectDB(MONGO_DB);
  }

  /**
   * Little helper function to add a new client to the database.
   *
   * Do NOT use this in production! This sample code stores the secret
   * in plaintext!
   *
   * @param $client_id
   *   Client identifier to be stored.
   * @param $client_secret
   *   Client secret to be stored.
   * @param $redirect_uri
   *   Redirect URI to be stored.
   */
  public function addClient($client_id, $client_secret, $redirect_uri) {
	$this->db->clients->insert(array(
	  "_id" => $client_id,
	  "pw" => $client_secret,
	  "redirect_uri" => $redirect_uri
	));
  }
  
  public function getClient($client_id){
  	return $this->db->clients->findOne(array("_id" => $client_id));
  }

  /**
   * Implements OAuth2::checkClientCredentials().
   *
   * Do NOT use this in production! This sample code stores the secret
   * in plaintext!
   */
  protected function checkClientCredentials($client_id, $client_secret = NULL) {
	$client = $this->db->clients->findOne(array("_id" => $client_id, "pw" => $client_secret));
	return $client !== NULL;
  }

  /**
   * Implements OAuth2::getRedirectUri().
   */
  protected function getRedirectUri($client_id) {
	$uri = $this->db->clients->findOne(array("_id" => $client_id), array("redirect_uri"));
	return $uri !== NULL ? $uri["redirect_uri"] : FALSE;
  }

  /**
   * Implements OAuth2::getAccessToken().
   */
  public function getAccessToken($oauth_token) {
	return $this->db->tokens->findOne(array("_id" => $oauth_token));
  }

  /**
   * Implements OAuth2::setAccessToken().
   */
  protected function setAccessToken($oauth_token, $client_id, $expires, $scope = NULL, $params=array()) {
	  extract($params);

	$record_info = array(
		"_id" => $oauth_token,
		"client_id" => $client_id,
		"expires" => $expires,
		"scope" => $scope,
		"user_id" => $user_id,
		"client_equipment_no" => $client_equipment_no,
	);	  
	 
	if(!empty($params)){

		$record_info = array_merge($params ,$record_info);
	}
	$this->db->tokens->insert($record_info, array('safe'=>1, 'j'=>true));
  }

  /**
   * Overrides OAuth2::getSupportedGrantTypes().
   */
  protected function getSupportedGrantTypes() {
	return array(
	  OAUTH2_GRANT_TYPE_AUTH_CODE,
	);
  }

  /**
   * Overrides OAuth2::getAuthCode().
   */
protected function getAuthCode($code) {
	$stored_code = $this->db->auth_codes->findOne(array("_id" => $code));

	return $stored_code !== NULL ? $stored_code : FALSE;
  }

  /**
   * Overrides OAuth2::setAuthCode().
   */
  protected function setAuthCode($code, $client_id, $redirect_uri, $expires, $scope = NULL, $params=array()) {
	  extract($params);
	$this->db->auth_codes->insert(array(
	  "_id" => $code,
	  "client_id" => $client_id,
	  "redirect_uri" => $redirect_uri,
	  "expires" => $expires,
	  "scope" => $scope,
		"user_id" => $user_id,
		"user_name" => $user_name,
	));
  }

	public function setAuthUser($client_id, $user_id)
	{
		$auth_user = $this->getAuthUser($client_id, $user_id);
		if(!$auth_user)
		{
			$create_time = date('Y-m-d H:i:s');
			$this->db->auth_users->insert(array(
			"client_id" => $client_id,
			"user_id" => $user_id,
			"create_time" => $create_time,
			));
		}
	}
	
	

	public function getAuthUser($client_id, $user_id)
	{
		return $this->db->auth_users->findOne(array("client_id" =>$client_id,"user_id"=>$user_id));
	}
	
	
	/**
	 * 是否为有效token
	 * @param unknown $access_token
	 */
	public function isValidToken($access_token){

		$token_info =  $this->db->tokens->findOne(array("_id" => $access_token));
		if(empty($token_info)) return 'N';
		return (strtotime("now") >= $token_info['expires']) ? 'N' : 'Y';
	}
	

	/**
	 * 获取有效token
	 * @param unknown $user_id
	 * @param string $client_id
	 */
	public function getValidToken($user_id, $client_id=''){
		
		$condition_list = array("user_id"=>$user_id,"is_valid"=>'Y','expires'=>array('$gt'=>strtotime("now")));
		if(!empty($client_id)){

			$condition_list['client_id'] = $client_id;
		}
		return  $this->db->tokens->findOne($condition_list);
		
	}
	

	/**
	 * 除参数中oauth_token外将用户其他oauth_token置为无效
	 * @param unknown $user_id
	 * @param unknown $oauth_token
	 * @param string $client_id
	 */
	public function setInValidExceptForToken($user_id, $oauth_token, $client_id=''){

		$where_list = array('user_id'=>strval($user_id), '_id'=>array('$ne'=>$oauth_token));
		if(!empty($client_id)){

			$where_list['client_id'] = $client_id;
		}
		return $this->db->tokens->update($where_list,array('$set'=>array('is_valid'=>'N')));
	}

	/**
	 * 将当前用户在某个终端全部设置为无效
	 * @param unknown $user_id
	 * @param unknown $oauth_token
	 * @param string $client_id
	 */
	public function setInValidExceptForAll($user_id, $client_id=''){
	
		$where_list = array('user_id'=>strval($user_id), 'is_valid'=>array('$eq'=>'Y'));
		if(!empty($client_id)){
	
			$where_list['client_id'] = $client_id;
		}
		return $this->db->tokens->update($where_list,array('$set'=>array('is_valid'=>'N')));
	}
	

	public function setTokenExpireByToken($oauth_token)
	{
		return $this->db->tokens->update(array("_id" => $oauth_token),array('$set'=>array('expires'=>strtotime("now"))));
	}
	
	public function setTokenExpireByUser($user_id)
	{
		return $this->db->tokens->update(array("user_id" => strval($user_id)),array('$set'=>array('expires'=>strtotime("now"))));
	}
}
